package com.danbay.framework.redis.config;

import com.danbay.framework.redis.RedisClient;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

/**
 *
 * @author SJG
 * @date 2017/9/29
 */

@Configuration
@ConditionalOnClass(RedisTemplate.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@Data
public class RedisConfigurator {

    @Configuration
    protected static class RedisConfiguration {
        protected RedisConfiguration() {
        }

        @Bean
        public StringRedisSerializer getStringRedisSerializer(){
            return new StringRedisSerializer();
        }

        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, StringRedisSerializer redisSerializer) throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate();
            template.setKeySerializer(redisSerializer);
            // 使用Jackson2JsonRedisSerialize 替换默认序列化
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

        @Bean
        public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory, StringRedisSerializer redisSerializer) throws UnknownHostException {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setKeySerializer(redisSerializer);
            template.setHashKeySerializer(redisSerializer);
            template.setValueSerializer(redisSerializer);
            template.setHashValueSerializer(redisSerializer);
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }

    @Bean
    public RedisClient getRedisClient(RedisTemplate<Object, Object> redisTemplate, StringRedisTemplate stringRedisTemplate){
        return new RedisClient(redisTemplate, stringRedisTemplate);
    }
}
